#pragma once
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif

#include <iostream>
#include<json/json.h>



//#define MySelf 1

std::string blank_space_sep = " ";
std::string protocol_sep = "\n";

// 封装报头
std::string EnHeader(const std::string &content)
{
    // 封装成："len\nx op y\n",len表示正文代码(有效载荷)长度
    std::string package;
    package += std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// 解封报头
bool DeHeader(std::string &Package, std::string &content)
{
    // 将"len\nx op y\n"字符串转换成"x op y"
    // 首先判断读取到的报文长度是否符合定制的要求
    auto pos = Package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = Package.substr(0, pos);
    int len = std::stoi(len_str);
    int total_len = len + 2 + len_str.size();
    if (Package.size() < total_len)
        return false;
    // 报文内容正确
    content = Package.substr(pos + 1, len);
    //处理完报文，我们需要将处理的删除，以便下一次读取成功
    Package.erase(0,total_len);
    return true;
}

struct Request
{
    Request(int data1, int data2, char op)
        : data1_(data1), data2_(data2), op_(op)
    {
    }

    Request()
    {
    }

    bool Serialize(std::string &out)
    {
#ifdef MySelf
        // 构建报文有效载荷:  "x op y"
        std::string s = std::to_string(data1_);
        s += blank_space_sep;
        s += op_;
        s += blank_space_sep;
        s += std::to_string(data2_);

        // 输出序列化字符串
        out = s;
        return true;
#else
        Json::Value root;
        root["data1"] = data1_;
        root["data2"] = data2_;
        root["op"] = op_;
        Json::FastWriter w;
        out = w.write(root);
        return true;
#endif
    }

    bool DeSerialize(const std::string &in)
    {
#ifdef MySelf
        // 将字符串反序列化为结构体:"x op y"
        auto lsep = in.find(blank_space_sep);
        if (lsep == std::string::npos)
            return false;
        std::string part_l = in.substr(0, lsep);
        auto rsep = in.rfind(blank_space_sep);
        std::string part_r = in.substr(rsep);
        if (lsep + 2 != rsep)
            return false;
        char op = in[lsep + 1];

        data1_ = std::stoi(part_l);
        data2_ = std::stoi(part_r);
        op_ = op;
        return true;
#else
        Json::Value v;
        Json::Reader r;
        r.parse(in,v);
        data1_ = v["data1"].asInt();
        data2_ = v["data2"].asInt();
        op_ = v["op"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        std::cout << "请求构建成功: " << data1_ << op_ << data2_ << "= ?" << std::endl;
    }

    ~Request()
    {
    }

    int data1_;
    int data2_;
    char op_;
};

struct Response
{
    Response(int result, int code)
        : result_(result), code_(code)
    {
    }

    Response()
    {
    }

    bool Serialize(std::string &out)
    {
#ifdef MySelf
        
        // 构建报文有效载荷:  "result code"
        std::string s = std::to_string(result_);
        s += blank_space_sep;
        s += std::to_string(code_);

        // 输出序列化字符串
        out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result_;
        root["code"] = code_;
        Json::FastWriter w;
        out = w.write(root);
        return true;
#endif
    }

    bool DeSerialize(const std::string &in)
    {
#ifdef MySelf
        // 将字符串反序列化为结构体:"x op y"
        auto pos = in.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        result_ = std::stoi(in.substr(0, pos));
        code_ = std::stoi(in.substr(pos + 1));

        return true;
#else
        Json::Value v;
        Json::Reader r;
        r.parse(in,v);
        result_ = v["result"].asInt();
        code_ = v["code"].asInt();
        return true;
#endif
    }
    void DebugPrint()
    {
        std::cout << "服务响应成功,result: " << result_ << ", code: " << code_ << std::endl;
    }
    ~Response()
    {
    }

    int result_;
    int code_;
};